import json
import random
import string
import time

import coin.exchange.base.kr_ws.ws_client_base as wscb
from coin.exchange.upbit_v1.kr_rest.product import UpbitProduct
from coin.exchange.upbit_v1.kr_ws.upbit_parser import UpbitParserManager
from coin.exchange.base.kr_ws.ws_parser_base import (WsFeedPrinter, WsFeedArchiver)


class UpbitWsRequest(wscb.WebsocketRequestBase):
  def FromSingleProduct(product):
    return UpbitWsRequest([product], [product])

  def __init__(self, book_symbols=None, trade_symbols=None, recent_symbols=None):
    self.book_symbols = UpbitProduct.FromAnyList(book_symbols)
    self.trade_symbols = UpbitProduct.FromAnyList(trade_symbols)
    self.recent_symbols = UpbitProduct.FromAnyList(recent_symbols)
    self.product = self.book_symbols[0]

  def as_request_str(self):
    lst = []
    lst.append(dict(ticket="ram macbook",))
    lst.append(dict(format="SIMPLE",))
    if self.recent_symbols is not None:
      lst.append(dict(
          type="crixRecent",
          codes=[x.native_symbol_crix for x in self.recent_symbols],
      ))
    if self.trade_symbols is not None:
      lst.append(dict(
          type="crixTrade",
          codes=[x.native_symbol_crix for x in self.trade_symbols],
      ))
    if self.book_symbols is not None:
      lst.append(
          dict(
              type="crixOrderbook",
              codes=[x.native_symbol_crix for x in self.book_symbols],
          ))
    lst_str = json.dumps(lst, separators=(',', ':'))
    lst2 = [lst_str]
    lst2_str = json.dumps(lst2, separators=(',', ':'))
    return lst2_str


class UpbitWSClient(wscb.WebsocketClientBase):
  RequestType = UpbitWsRequest

  @staticmethod
  def gen_address():
    return "wss://crix-websocket.upbit.com/sockjs/%s/%s/websocket" % (
        "".join(random.choices(string.digits, k=3)),
        "".join(random.choices(string.ascii_lowercase, k=8)))

  def __init__(self, request, feed_handler):
    wscb.WebsocketClientBase.__init__(self,
                                      url=UpbitWSClient.gen_address(),
                                      request=request,
                                      handler=UpbitParserManager(feed_handler))
    self.request_str = self._request.as_request_str()

  def _connect_impl(self):
    msg = self._recv()
    assert "o" == msg.msg
    self._send(self.request_str)

  def _disconnect_impl(self):
    pass

  def _heartbeat_impl(self):
    self._send(self.request_str)


if __name__ == "__main__":
  request = UpbitWsRequest(book_symbols=["ETH-KRW"], trade_symbols=["ETH-KRW"])
  wsClient = UpbitWSClient(request, WsFeedPrinter(verbose=False))
  wsClient.start()
  wsClient.printInfo()
  while (wsClient.getRecvMsgCount() < 100):
    print("RecvMsgCount =", "%i" % wsClient.getRecvMsgCount())
    time.sleep(1)
  wsClient.stop()
